package com.lyon.demo.netty.core.bytebuf;

import com.lyon.demo.rpc.api.core.Command;
import com.lyon.demo.rpc.api.core.Header;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * @author LeeYan9
 * @since 2022-04-18
 */
@SuppressWarnings("unused")
public class CommandDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
        // 判断可读数
        if (!byteBuf.isReadable(Integer.BYTES)) {
            return;
        }
        // 标记..?
        byteBuf.markReaderIndex();
        // 获取头信息里，整体数据的字节长度
        int length = byteBuf.readInt() - Integer.BYTES;
        // 可读字节数 小于 标识的字节长度
        if (byteBuf.readableBytes() < length) {
            byteBuf.resetReaderIndex();
            return;
        }
        Command command = new Command();

        // decoder header
        Header header = headerDecoder(ctx, byteBuf);
        command.setHeader(header);
        // decoder command-payload
        decoderCommand(ctx, byteBuf, length, command);
        out.add(command);
    }

    protected Header headerDecoder(ChannelHandlerContext ctx, ByteBuf byteBuf) {
        int type = byteBuf.readInt();
        int version = byteBuf.readInt();
        long requestId = byteBuf.readLong();
        return new Header(type, requestId, version);
    }


    protected void decoderCommand(ChannelHandlerContext ctx, ByteBuf byteBuf, int length, Command command) {
        int headerLength = command.getHeader().length();
        int payloadLength = length - headerLength;
        byte[] payload = new byte[payloadLength];
        command.setPayload(payload);
        byteBuf.readBytes(payload);
    }
}
